import { BlockEnum } from '@/components/workflow/types'
import { generateUniqueNodeId } from '@/store/workflowStore'
import { generateUUID } from '@/utils'
import { ComponentType } from 'react'
import { Position } from 'reactflow'  // 添加这行导入
// 代码节点
import CodeDefault, { getCodeDefaultParams } from './nodes/code/default'
import CodeNode from './nodes/code/node'
import CodePanel from './nodes/code/panel'
// 结束节点
import EndNodeDefault from './nodes/end/default'
import EndNode from './nodes/end/node'
import EndPanel from './nodes/end/panel'
// 条件分支节点
import IfElseDefault, { getIfElseDefaultParams } from './nodes/if-else/default'
import IfElseNode from './nodes/if-else/node'
import IfElsePanel from './nodes/if-else/panel'
// 意图识别节点
import IntentDefault, { getIntentDefaultParams } from './nodes/intent/default'
import IntendNode from './nodes/intent/node'
import IntentPanel from './nodes/intent/panel'
// 知识库节点
import KnowledgeDefault, { getKnowledgeDefaultParams } from './nodes/knowledge/default'
import KnowledgeNode from './nodes/knowledge/node'
import KnowledgePanel from './nodes/knowledge/panel'
// 大模型节点
import LLMDefault, { getLlmDefaultParams } from './nodes/llm/default'
import LLMNode from './nodes/llm/node'
import LLMPanel from './nodes/llm/panel'
// 开始节点
import StartNodeDefault from './nodes/start/default'
import StartNode from './nodes/start/node'
import StartPanel from './nodes/start/panel'
// 文档提取器
import DocExtractorDefault,{ getExtractorDefaultParams } from './nodes/doc-extractor/default'
import DocExtractorNode from './nodes/doc-extractor/node'
import DocExtractorPanel from './nodes/doc-extractor/panel'

// 迭代器
import IterationDefault,{ getIterationDefaultParams } from './nodes/iteration/default'
import IterationNode from './nodes/iteration/node'
import IterationPanel from './nodes/iteration/panel'

// 迭代器开始
import IterationStartDefault,{ getIterationStartDefaultParams } from './nodes/iteration-start/default'
import IterationStartNode from './nodes/iteration-start/node'

// 迭代器结束
import IterationEndDefault, { getIterationEndDefaultParams } from './nodes/iteration-end/default'
import IterationEndNode from './nodes/iteration-end/node'
import IterationEndPanel from './nodes/iteration-end/panel'

// HTTP请求
import HttpRequestDefault,{ getHttpRequestDefaultParams } from './nodes/http-request/default'
import HttpRequestNode from './nodes/http-request/node'
import HttpRequestPanel from './nodes/http-request/panel'

//文本拼接
import TextConcatenationDefault, { getTextConcatenationDefaultParams } from './nodes/text-concatenation/default'
import TextConcatenationNode from './nodes/text-concatenation/node'
import TextConcatenationPanel from './nodes/text-concatenation/panel'

//变量更新
import VarUpdateDefault, { getVarUpdateDefaultParams } from './nodes/var-update/default'
import VarUpdateNode from './nodes/var-update/node'
import VarUpdatePanel from './nodes/var-update/panel'

//列表操作
import ListDefault, { getListDefaultParams } from './nodes/list/default'
import ListNode from './nodes/list/node'
import ListPanel from './nodes/list/panel'

//列表操作
import LoopDefault, { getLoopDefaultParams } from './nodes/loop/default'
import LoopNode from './nodes/loop/node'
import LoopPanel from './nodes/loop/panel'

// 迭代器开始
import LoopStartDefault,{ getLoopStartDefaultParams } from './nodes/loop-start/default'
import LoopStartNode from './nodes/loop-start/node'

// 迭代器结束
import LoopEndDefault, { getLoopEndDefaultParams } from './nodes/loop-end/default'
import LoopEndNode from './nodes/loop-end/node'
import LoopEndPanel from './nodes/loop-end/panel'

// 工具节点
import ToolDefault, { getToolDefaultParams } from './nodes/tool/default'
import ToolNode from './nodes/tool/node'
import ToolPanel from './nodes/tool/panel'
import { InputVar } from './nodes/types'
import WorkflowNode from './nodes/workflow/node'
import {FlowNode } from '@/components/workflow/types'
import node from './nodes/code/node'
export const WORKFLOW_DATA_UPDATE = 'WORKFLOW_DATA_UPDATE'
export const CUSTOM_NODE = 'flowNode'
export const DSL_EXPORT_CHECK = 'DSL_EXPORT_CHECK'

export const NodeComponentMap: Record<string, ComponentType<any>> = {
  [BlockEnum.Start]: StartNode,
  [BlockEnum.End]: EndNode,
  [BlockEnum.Code]: CodeNode,
  [BlockEnum.LLM]: LLMNode,
  [BlockEnum.IfElse]: IfElseNode,
  [BlockEnum.KnowledgeRetrieval]: KnowledgeNode,
  [BlockEnum.Tool]: ToolNode,
  [BlockEnum.Intend]: IntendNode,
  [BlockEnum.Workflow]: WorkflowNode,
  [BlockEnum.DocExtractor]: DocExtractorNode,
  [BlockEnum.Iteration]: IterationNode,
  [BlockEnum.IterationStart]: IterationStartNode ,
  [BlockEnum.IterationEnd]: IterationEndNode ,
  [BlockEnum.HttpRequest]: HttpRequestNode, // Add this line
  [BlockEnum.TextConcatenation]: TextConcatenationNode,
  [BlockEnum.VarUpdate]: VarUpdateNode,
  [BlockEnum.List]: ListNode,
  [BlockEnum.Loop]: LoopNode,
  [BlockEnum.LoopStart]: LoopStartNode,
  [BlockEnum.LoopEnd]: LoopEndNode,
}

export const PanelComponentMap: Record<string, ComponentType<any>> = {
  [BlockEnum.Start]: StartPanel,
  [BlockEnum.End]: EndPanel,
  [BlockEnum.Code]: CodePanel,
  [BlockEnum.LLM]: LLMPanel,
  [BlockEnum.IfElse]: IfElsePanel,
  [BlockEnum.KnowledgeRetrieval]: KnowledgePanel,
  [BlockEnum.Tool]: ToolPanel,
  [BlockEnum.Intend]: IntentPanel,
  [BlockEnum.Workflow]: WorkflowNode,
  [BlockEnum.DocExtractor]: DocExtractorPanel,
  [BlockEnum.Iteration]: IterationPanel,
  [BlockEnum.IterationEnd]: IterationEndPanel,
  [BlockEnum.HttpRequest]: HttpRequestPanel, // Add this line
  [BlockEnum.TextConcatenation]: TextConcatenationPanel,
  [BlockEnum.VarUpdate]: VarUpdatePanel,
  [BlockEnum.List]: ListPanel,
  [BlockEnum.Loop]: LoopPanel,
  [BlockEnum.LoopEnd]: LoopEndPanel,
}

export const ComponentDescMap: Record<string, string> = {
  [BlockEnum.Start]: '工作流的起始节点，用于设定启动工作流需要的信息',
  [BlockEnum.End]: '工作流的最终节点，用于返回工作流运行后的结果信息',
  [BlockEnum.Code]: '编写代码，处理输入变量来生成返回值',
  [BlockEnum.LLM]: '调用大语言模型,使用变量和提示词生成回复',
  [BlockEnum.IfElse]: '连接多个下游分支，若设定的条件成立则仅运行对应的分支，若均不成立则只运行“否则”分支',
  [BlockEnum.KnowledgeRetrieval]: '在选定的知识中,根据输入变量召回最匹配的信息,并以列表形式返回',
  [BlockEnum.Tool]: '通过添加工具访问实时数据和执行外部操作',
  [BlockEnum.Intend]: '用于用户输入的意图识别，并将其与预设意图选项进行匹配',
  [BlockEnum.Workflow]: '集成已发布工作流，可以执行嵌套子任务',
  [BlockEnum.DocExtractor]: '从文档提取内容输出内容',
  [BlockEnum.Iteration]: '遍历列表中的每个元素，并执行相应的子流程操作',
  [BlockEnum.IterationStart]: '迭代开始',
  [BlockEnum.HttpRequest]: '发送HTTP请求并处理响应结果', // Add this line
  [BlockEnum.TextConcatenation]: '将多个文本按照指定分隔符拼接成一个字符串',
  [BlockEnum.VarUpdate]: '可以更新指定节点的输出值或更新全局变量',
  [BlockEnum.IterationEnd]: '迭代结束',
  [BlockEnum.List]: '用于过滤或者排序数组中的元素',
  [BlockEnum.Loop]: '循环一段逻辑直到满足结束条件或者达到最大迭代次数',
  [BlockEnum.LoopStart]: '循环开始',
  [BlockEnum.LoopEnd]: '循环结束',
}

export const CUSTOM_NODE_TYPE = 'flowNode'

export const workflowTemplateList = [
  // {
  //   desc: ComponentDescMap[BlockEnum.Start],
  //   title: '开始',
  //   node_type: ComponentDescMap[BlockEnum.Start],
  //   isInIteration: false, // 节点链接状态
  //   support_batch: 1,
  //   type: BlockEnum.Start
  // },
  {
    desc: ComponentDescMap[BlockEnum.LLM],
    title: '大模型',
    node_type: BlockEnum.LLM,
    isInIteration: false, // 节点链接状态
    support_batch: 2,
    type: BlockEnum.LLM,
    ...getLlmDefaultParams()
  },
  {
    desc: ComponentDescMap[BlockEnum.KnowledgeRetrieval],
    title: '知识库',
    node_type: BlockEnum.KnowledgeRetrieval,
    isInIteration: false, // 节点链接状态
    support_batch: 1,
    type: BlockEnum.KnowledgeRetrieval,
    ...getKnowledgeDefaultParams()
  },
  {
    desc: ComponentDescMap[BlockEnum.Tool],
    title: '插件',
    node_type: BlockEnum.Tool,
    isInIteration: false, // 节点链接状态
    support_batch: 2,
    type: BlockEnum.Tool,
    ...getToolDefaultParams()
  },
  {
    desc: ComponentDescMap[BlockEnum.Code],
    title: '代码',
    node_type: BlockEnum.Code,
    isInIteration: false, // 节点链接状态
    support_batch: 1,
    type: BlockEnum.Code,
    ...getCodeDefaultParams()
  },
  {
    desc: ComponentDescMap[BlockEnum.Intend],
    title: '意图识别',
    node_type: BlockEnum.Intend,
    isInIteration: false, // 节点链接状态
    support_batch: 2,
    type: BlockEnum.Intend,
    ...getIntentDefaultParams()
  },
  {
    desc: ComponentDescMap[BlockEnum.IfElse],
    title: '选择器',
    node_type: BlockEnum.IfElse,
    isInIteration: false, // 节点链接状态
    support_batch: 1,
    type: BlockEnum.IfElse,
    ...getIfElseDefaultParams()
  },
  {
    desc: ComponentDescMap[BlockEnum.DocExtractor],
    title: '文档提取器',
    node_type: BlockEnum.DocExtractor,
    isInIteration: false, // 节点链接状态
    support_batch: 1,
    type: BlockEnum.DocExtractor,
    ...getExtractorDefaultParams()
  },
  {
    desc: ComponentDescMap[BlockEnum.Iteration],
    title: '迭代',
    node_type: BlockEnum.Iteration,
    isInIteration: false, // 节点链接状态
    support_batch: 1,
    type: BlockEnum.Iteration,
    ...getIterationDefaultParams()
  },
  {
    desc: ComponentDescMap[BlockEnum.HttpRequest],
    title: 'HTTP请求',
    node_type: BlockEnum.HttpRequest,
    isInIteration: false, // 节点链接状态
    support_batch: 1,
    type: BlockEnum.HttpRequest,
    ...getHttpRequestDefaultParams()
  },
  {
    desc: ComponentDescMap[BlockEnum.TextConcatenation],
    title: '文本拼接',
    node_type: BlockEnum.TextConcatenation,
    isInIteration: false,
    support_batch: 1,
    type: BlockEnum.TextConcatenation,
    ...getTextConcatenationDefaultParams()
  },
  {
    desc: ComponentDescMap[BlockEnum.VarUpdate],
    title: '变量更新',
    node_type: BlockEnum.VarUpdate,
    isInIteration: false,
    support_batch: 1,
    type: BlockEnum.VarUpdate,
    ...getVarUpdateDefaultParams()
  },
  {
    desc: ComponentDescMap[BlockEnum.List],
    title: '列表操作',
    node_type: BlockEnum.List,
    isInIteration: false,
    support_batch: 1,
    type: BlockEnum.List,
    ...getListDefaultParams()
  },
  {
    desc: ComponentDescMap[BlockEnum.Loop],
    title: '循环',
    node_type: BlockEnum.Loop,
    isInIteration: false,
    support_batch: 1,
    type: BlockEnum.Loop,
    ...getLoopDefaultParams()
  }
  // {
  //   desc: ComponentDescMap[BlockEnum.IterationEnd],
  //   title: '迭代结束',
  //   node_type: BlockEnum.IterationEnd,
  //   isInIteration: false,
  //   support_batch: 1,
  //   type: BlockEnum.IterationEnd,
  //   ...getIterationEndDefaultParams()
  // },
  // {
  //   desc: ComponentDescMap[BlockEnum.Workflow],
  //   title: '工作流',
  //   node_type: BlockEnum.Workflow,
  //   isInIteration: false, // 节点链接状态
  //   support_batch: 2,
  //   type: BlockEnum.Workflow
  // },
  // {
  //   desc: ComponentDescMap[BlockEnum.End],
  //   title: '结束',
  //   node_type: BlockEnum.End,
  //   isInIteration: false, // 节点链接状态
  //   support_batch: 1,
  //   type: BlockEnum.End
  // }
]


export const startFirstInputParams = (): InputVar => {
  return {
    id: generateUUID(8),
    type: 'string',
    label: '本轮对话的输入',
    variable: 'input',
    value: '',
    max_length: 10,
    default: '',
    required: true
  }
}
export const endFirstOutputParams = (): InputVar => {
  return {
    id: generateUUID(8),
    type: 'cite',
    label: '',
    variable: 'output',
    value: '',
    max_length: 10,
    default: '',
    required: true,
    options: [],
    value_selector: []
  }
}
// 输入节点默认数据
export const startInputParams = (): InputVar => {
  return {
    id: generateUUID(8),
    type: 'string',
    label: '',
    variable: '',
    value: '',
    max_length: 10,
    default: '',
    required: true
  }
}

// 输出节点默认数据
export const endInputParams = (): InputVar => {
  return {
    id: generateUUID(8),
    type: 'cite',
    label: '',
    variable: '',
    value: undefined,
    max_length: 10,
    default: '',
    required: true,
    options: [],
    value_selector: []
  }
}
export const getStartNode = () => {
  const newId = generateUniqueNodeId('start')
  return {
    id: newId,
    type: 'flowNode',
    position: {
      x: 50,
      y: 200
    },
    data: {
      desc: ComponentDescMap[BlockEnum.Start],
      id: newId,
      title: '开始',
      node_type: BlockEnum.Start,
      support_batch: 2,
      type: BlockEnum.Start,
      isInIteration: false, // 节点链接状态
      //variables: [startFirstInputParams()]
      variables: []
    }
  }
}


export const getIterationStartNode = (parentId: string, nodeId: string, position: { x: number, y: number }): FlowNode => {
  const data= {
      desc: ComponentDescMap[BlockEnum.IterationStart],
      id: nodeId,
      title: ComponentDescMap[BlockEnum.IterationStart],
      type: BlockEnum.IterationStart,
      isInIteration: false,
      node_type: BlockEnum.IterationStart,
      parentId: parentId
  }
  
  return {
    id: nodeId,
    type: 'flowNode',
    parentId: parentId,
    extent: 'parent',
    position: position,
    sourcePosition: Position.Right,  // 右侧显示连接点
    data: {
      ...data
    }
  }
}

export const getIterationEndNode = (parentId: string, nodeId: string, position: { x: number, y: number }): FlowNode => {
  const data = {
    desc: ComponentDescMap[BlockEnum.IterationEnd],
    id: nodeId,
    title: ComponentDescMap[BlockEnum.IterationEnd],
    type: BlockEnum.IterationEnd,
    isInIteration: false,
    ...getIterationEndDefaultParams(),
    node_type: BlockEnum.IterationEnd,
    parentId: parentId,
  }

  return {
    id: nodeId,
    type: 'flowNode',
    parentId: parentId,
    extent: 'parent',
    position: position,
    sourcePosition: Position.Right,  // 右侧显示连接点
    data: {
      ...data
    }
  }
}

export const getLoopStartNode = (parentId: string, nodeId: string, position: { x: number, y: number }): FlowNode => {
  const data= {
      desc: ComponentDescMap[BlockEnum.LoopStart],
      id: nodeId,
      title: ComponentDescMap[BlockEnum.LoopStart],
      type: BlockEnum.LoopStart,
      isInIteration: false,
      node_type: BlockEnum.LoopStart,
  }
  
  return {
    id: nodeId,
    type: 'flowNode',
    parentId: parentId,
    extent: 'parent',
    position: position,
    sourcePosition: Position.Right,  // 右侧显示连接点
    data: {
      ...data
    }
  }
}

export const getLoopEndNode = (parentId: string, nodeId: string, position: { x: number, y: number }): FlowNode => {
  const data = {
    desc: ComponentDescMap[BlockEnum.LoopEnd],
    id: nodeId,
    title: ComponentDescMap[BlockEnum.LoopEnd],
    type: BlockEnum.LoopEnd,
    isInIteration: false,
    ...getLoopEndDefaultParams(),
    node_type: BlockEnum.LoopEnd,
  }

  return {
    id: nodeId,
    type: 'flowNode',
    parentId: parentId,
    extent: 'parent',
    position: position,
    sourcePosition: Position.Left,  // 右侧显示连接点
    data: {
      ...data
    }
  }
}

export const getEndNode = () => {
  const newId = generateUniqueNodeId('end')
  return {
    id: newId,
    type: 'flowNode',
    position: {
      x: 850,
      y: 200
    },
    data: {
      desc: '工作流的最终节点，用于返回工作流运行后的结果信息',
      id: newId,
      title: '结束',
      node_type: BlockEnum.End,
      support_batch: 1,
      type: BlockEnum.End,
      isInIteration: false, // 节点链接状态
      outputType: 'outputs',
      outputs: [endFirstOutputParams()]
    }
  }
}

// flow创建时自动生成开始结束节点
export const initNodeData = () => {
  return {
    nodes: [getStartNode(), getEndNode()],
    edges: [],
    viewport: {
      x: 0,
      y: 0,
      zoom: getZoomByScreen()
    }
  }
}

export const getZoomByScreen = () => {
  const screenWidth = window.innerWidth
  const baseWidth = 1200 // 基准宽度
  const baseZoom = 0.8 // 基准缩放值
  const zoomIncrement = 0.2 // 每增加200宽度的缩放增量
  const widthIncrement = 500 // 宽度增量

  const zoom = baseZoom + Math.max(0, (screenWidth - baseWidth) / widthIncrement) * zoomIncrement
  return zoom
}

// 变量类型 选择器
export const variableTypeOptions = [
  { value: 'string', label: '文本' },
  //{ value: 'integer', label: 'Integer' },
  { value: 'boolean', label: '开关' },
  { value: 'number', label: '数字' },
  { value: 'file', label: '单文件' },
  { value: 'array_file', label: '文件列表' }
]

export const STRING = 'string'
export const INTEGER = 'integer'
export const BOOLEAN = 'boolean'
export const NUMBER = 'number'
export const FILE = 'file'
export const ARRAY_FILES = 'array_file'
export const ARRAY = "array"

export const variableSourceTypeOptions = [
  { value: 'cite', label: '引用' },
  { value: 'input', label: '输入' }
]
export const variableSourceTypeOptions_tool = [
  { value: 'cite', label: '引用' },
  { value: 'input', label: '输入' },
  { value: 'default', label: '默认' }
]

/* 选择器判断条件 */
export const ifElseTypeOptions = [
  { value: 'equals', label: '等于' },
  { value: 'not_equals', label: '不等于' },
  { value: 'contains', label: '包含' },
  { value: 'not_contains', label: '不包含' },
  { value: 'is_empty', label: '为空' },
  { value: 'is_not_empty', label: '不为空' },
  { value: 'starts_with', label: '开始为' },
  { value: 'ends_with', label: '结束为' }
  // { value: 'greater_than', label: '>' },
  // { value: 'less_than', label: '<' },
  // { value: 'greater_than_or_equal', label: '≥' },
  // { value: 'less_than_or_equal', label: '≤' },
  // { value: 'regex', label: '正则' }
]

export const stringOperatorOptions = [
  { value: 'equals', label: '等于' },
  { value: 'not_equals', label: '不等于' },
  { value: 'contains', label: '包含' },
  { value: 'not_contains', label: '不包含' },
  { value: 'is_empty', label: '为空' },
  { value: 'is_not_empty', label: '不为空' },
  { value: 'starts_with', label: '开始为' },
  { value: 'ends_with', label: '结束为' }
]

export const numberOperatorOptions = [
  { value: 'equals', label: '=' },
  { value: 'not_equals', label: '≠' },
  { value: 'greater_than"', label: '>' },
  { value: 'less_than"', label: '<' },
  { value: 'greater_than_or_equal', label: '≥' },
  { value: 'less_than_or_equal', label: '≤' },
]

export const objectOperatorOptions =[
  { value: 'is_empty', label: '为空' },
  { value: 'is_not_empty', label: '不为空' }
]

export const arrayOperatorOptions = [
  { value: 'contains', label: '包含' },
  { value: 'not_contains', label: '不包含' },
  { value: 'is_empty', label: '为空' },
  { value: 'is_not_empty', label: '不为空' }
]

export const exetensionOperatorOptions = [
  { value: 'contains', label: '包含' },
  { value: 'not_contains', label: '不包含' },
  { value: 'is', label: '是' },
  { value: 'is_not', label: '不是' },
]

const variableSourceTypeMap = {}
variableSourceTypeOptions.forEach(item => {
  variableSourceTypeMap[item.value] = item.label
})

export { variableSourceTypeMap }

// 获取下一个节点的名称
export const generateNextNodeName = (nodes, name = '大模型_') => {
  const existingTitles = nodes
    .map(node => node.data.title)
    .filter(title => title.startsWith(name))
    .map(title => parseInt(title.split('_')[1], 10))
    .filter(num => !isNaN(num))

  if (existingTitles.length === 0) {
    return `${name}1`
  }

  const maxUsedNumber = Math.max(...existingTitles)
  const nextNumber = maxUsedNumber + 1

  return `${name}${nextNumber}`
}

type NodesExtraData = {
  author: string
  about: string
  availablePrevNodes: BlockEnum[]
  availableNextNodes: BlockEnum[]
  getAvailablePrevNodes: (isChatMode: boolean) => BlockEnum[]
  getAvailableNextNodes: (isChatMode: boolean) => BlockEnum[]
  checkValid: any
}

export enum NodesExtraEnum {
  Start = 'start',
  End = 'end',
  LLM = 'llm',
  Tool = 'tool',
  Intend = 'intend',
  IfElse = 'if-else',
  KnowledgeRetrieval = 'qa_retriever',
  Code = 'code',
  DocExtractor = 'doc_extractor',
  Iteration = 'iteration',
  IterationStart = 'iteration_start',
  IterationEnd = 'iteration_end',
  HttpRequest = 'http_request',
  TextConcatenation = 'text_concatenation',
  VarUpdater = 'var_update',
  List = 'list',
  Loop = 'loop',
  LoopStart = 'loop_start',
  LoopEnd = 'loop_end',
}

// 连线规则限制
export const NODES_EXTRA_DATA: Record<NodesExtraEnum, NodesExtraData> = {
  [BlockEnum.Start]: {
    author: 'Sky',
    about: '',
    availablePrevNodes: [],
    availableNextNodes: [],
    getAvailablePrevNodes: StartNodeDefault.getAvailablePrevNodes,
    getAvailableNextNodes: StartNodeDefault.getAvailableNextNodes,
    checkValid: StartNodeDefault.checkValid
  },
  [BlockEnum.End]: {
    author: 'Sky',
    about: '',
    availablePrevNodes: [],
    availableNextNodes: [],
    getAvailablePrevNodes: EndNodeDefault.getAvailablePrevNodes,
    getAvailableNextNodes: EndNodeDefault.getAvailableNextNodes,
    checkValid: EndNodeDefault.checkValid
  },
  [BlockEnum.LLM]: {
    author: 'Sky',
    about: '',
    availablePrevNodes: [],
    availableNextNodes: [],
    getAvailablePrevNodes: LLMDefault.getAvailablePrevNodes,
    getAvailableNextNodes: LLMDefault.getAvailableNextNodes,
    checkValid: LLMDefault.checkValid
  },
  [BlockEnum.Tool]: {
    author: 'Sky',
    about: '',
    availablePrevNodes: [],
    availableNextNodes: [],
    getAvailablePrevNodes: ToolDefault.getAvailablePrevNodes,
    getAvailableNextNodes: ToolDefault.getAvailableNextNodes,
    checkValid: ToolDefault.checkValid
  },
  [BlockEnum.Intend]: {
    author: 'Sky',
    about: '',
    availablePrevNodes: [],
    availableNextNodes: [],
    getAvailablePrevNodes: IntentDefault.getAvailablePrevNodes,
    getAvailableNextNodes: IntentDefault.getAvailableNextNodes,
    checkValid: IntentDefault.checkValid
  },
  [BlockEnum.IfElse]: {
    author: 'Sky',
    about: '',
    availablePrevNodes: [],
    availableNextNodes: [],
    getAvailablePrevNodes: IfElseDefault.getAvailablePrevNodes,
    getAvailableNextNodes: IfElseDefault.getAvailableNextNodes,
    checkValid: IfElseDefault.checkValid
  },
  [BlockEnum.KnowledgeRetrieval]: {
    author: 'Sky',
    about: '',
    availablePrevNodes: [],
    availableNextNodes: [],
    getAvailablePrevNodes: KnowledgeDefault.getAvailablePrevNodes,
    getAvailableNextNodes: KnowledgeDefault.getAvailableNextNodes,
    checkValid: KnowledgeDefault.checkValid
  },
  [BlockEnum.Code]: {
    author: 'Sky',
    about: '',
    availablePrevNodes: [],
    availableNextNodes: [],
    getAvailablePrevNodes: CodeDefault.getAvailablePrevNodes,
    getAvailableNextNodes: CodeDefault.getAvailableNextNodes,
    checkValid: CodeDefault.checkValid
  },
  [BlockEnum.DocExtractor]: {
    author: 'Sky',
    about: '',
    availablePrevNodes: [],
    availableNextNodes: [],
    getAvailablePrevNodes: DocExtractorDefault.getAvailablePrevNodes,
    getAvailableNextNodes: DocExtractorDefault.getAvailableNextNodes,
    checkValid: DocExtractorDefault.checkValid
  },
  [BlockEnum.Iteration]: {
    author: 'Sky',
    about: '',
    availablePrevNodes: [],
    availableNextNodes: [],
    getAvailablePrevNodes: IterationDefault.getAvailablePrevNodes,
    getAvailableNextNodes: IterationDefault.getAvailableNextNodes,
    checkValid: IterationDefault.checkValid
  },
  [BlockEnum.IterationStart]: {
    author: 'Sky',
    about: '',
    availablePrevNodes: [],
    availableNextNodes: [],
    getAvailablePrevNodes: IterationStartDefault.getAvailablePrevNodes,
    getAvailableNextNodes: IterationStartDefault.getAvailableNextNodes,
    checkValid: IterationStartDefault.checkValid
  },
  [BlockEnum.IterationEnd]: {
    author: 'Sky',
    about: '',
    availablePrevNodes: [],
    availableNextNodes: [],
    getAvailablePrevNodes: IterationEndDefault.getAvailablePrevNodes,
    getAvailableNextNodes: IterationEndDefault.getAvailableNextNodes,
    checkValid: IterationEndDefault.checkValid
  },
  [BlockEnum.HttpRequest]: {
    author: 'Sky',
    about: '',
    availablePrevNodes: [],
    availableNextNodes: [],
    getAvailablePrevNodes: HttpRequestDefault.getAvailablePrevNodes,
    getAvailableNextNodes: HttpRequestDefault.getAvailableNextNodes,
    checkValid: HttpRequestDefault.checkValid
  },
  [BlockEnum.TextConcatenation]: {
    author: 'Sky',
    about: '',
    availablePrevNodes: [],
    availableNextNodes: [],
    getAvailablePrevNodes: TextConcatenationDefault.getAvailablePrevNodes,
    getAvailableNextNodes: TextConcatenationDefault.getAvailableNextNodes,
    checkValid: TextConcatenationDefault.checkValid
  },
  [BlockEnum.VarUpdate]: {
    author: 'Sky',
    about: '',
    availablePrevNodes: [],
    availableNextNodes: [],
    getAvailablePrevNodes: VarUpdateDefault.getAvailablePrevNodes,
    getAvailableNextNodes: VarUpdateDefault.getAvailableNextNodes,
    checkValid: VarUpdateDefault.checkValid
  },
  [BlockEnum.List]: {
    author: 'Sky',
    about: '',
    availablePrevNodes: [],
    availableNextNodes: [],
    getAvailablePrevNodes: ListDefault.getAvailablePrevNodes,
    getAvailableNextNodes: ListDefault.getAvailableNextNodes,
    checkValid: ListDefault.checkValid
  },
  [BlockEnum.Loop]: {
    author: 'Sky',
    about: '',
    availablePrevNodes: [],
    availableNextNodes: [],
    getAvailablePrevNodes: LoopDefault.getAvailablePrevNodes,
    getAvailableNextNodes: LoopDefault.getAvailableNextNodes,
    checkValid: LoopDefault.checkValid
  },[BlockEnum.LoopStart]: {
    author: 'Sky',
    about: '',
    availablePrevNodes: [],
    availableNextNodes: [],
    getAvailablePrevNodes: LoopStartDefault.getAvailablePrevNodes,
    getAvailableNextNodes: LoopStartDefault.getAvailableNextNodes,
    checkValid: LoopStartDefault.checkValid
  },
  [BlockEnum.LoopEnd]: {
    author: 'Sky',
    about: '',
    availablePrevNodes: [],
    availableNextNodes: [],
    getAvailablePrevNodes: LoopEndDefault.getAvailablePrevNodes,
    getAvailableNextNodes: LoopEndDefault.getAvailableNextNodes,
    checkValid: LoopEndDefault.checkValid
  },
}

export const ALL_CHAT_AVAILABLE_BLOCKS = Object.keys(NODES_EXTRA_DATA).filter(
  key => key !== BlockEnum.End && key !== BlockEnum.Start
) as BlockEnum[]

export const ALL_COMPLETION_AVAILABLE_BLOCKS = Object.keys(NODES_EXTRA_DATA).filter(
  key => key !== BlockEnum.Answer && key !== BlockEnum.Start
) as BlockEnum[]
